package club.jdiy.admin.interceptor;

import club.jdiy.admin.entity.User;
import club.jdiy.core.AdminContext;
import club.jdiy.core.base.domain.Ret;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Method;

/**
 * 演示帐号拦截器．
 * 不允许在线演示帐号修改数据（便于他人演示正常）
 *
 * @version 20210706
 */
@Component
@Aspect
public class GuestInterceptor {

    @Around("@annotation(club.jdiy.admin.interceptor.GuestDisabled)")
    public Object refresh(ProceedingJoinPoint call) throws Throwable {
        Method method = getMethod(call);
        GuestDisabled anno = method.getAnnotation(GuestDisabled.class);

        if (anno == null) return call.proceed();

        User user = adminContext.getCurrentUser();
        return user.getRoleList().stream().noneMatch(r -> r.getId() == 2) ? call.proceed() : Ret.fail(Ret.RetCode.not_allowed.getCode(), "对不起，在线演示帐号不允许执行修改操作，如要体验完整功能，请下载后本地运行！");

    }

    private Method getMethod(ProceedingJoinPoint jp) {
        MethodSignature joinPointObject = (MethodSignature) jp.getSignature();
        Method tMethod = joinPointObject.getMethod();

        // 以下代码解决泛型参数Type变为Object，导致无法正常取得annotation的bug.
        Class<?>[] fixedParamTypes = tMethod.getParameterTypes();
        for (int i = 0; i < fixedParamTypes.length; i++) {
            if ("java.lang.Object".equals(fixedParamTypes[i].getName()))
                fixedParamTypes[i] = jp.getArgs()[i].getClass();
        }
        try {
            return jp.getTarget().getClass().getMethod(tMethod.getName(), fixedParamTypes);
        } catch (NoSuchMethodException nse) {
            // nse.printStackTrace();
            return tMethod;
        }
    }

    @Resource
    private AdminContext adminContext;

}